﻿using IOP.Pulsar.Abstractions;
using IOP.Pulsar.Default;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;

namespace IOP.Pulsar.Extensions
{
    /// <summary>
    /// 入口扩展
    /// </summary>
    public static class EntryServiceExtension
    {
        /// <summary>
        /// 添加默认入口
        /// </summary>
        /// <param name="services"></param>
        /// <returns></returns>
        public static IServiceCollection AddDefaultProductLineEntry(this IServiceCollection services)
        {
            services.AddSingleton<IProductLineBuilder<StringContext>, ProductLineBuilder<StringContext>>();
            services.AddSingleton<IProductLine<StringContext>>((factory) =>
            {
                var startups = factory.GetServices<IStartup>();
                var serverBuilder = factory.GetRequiredService<IServerBuilder>();
                var hostEnv = factory.GetRequiredService<IHostEnvironment>();
                foreach(var item in startups)
                    item.Configure(serverBuilder, hostEnv);
                var productLineBuilder = factory.GetRequiredService<IProductLineBuilder<StringContext>>();
                return new DefaultProductLine<StringContext>() { ProductLine = productLineBuilder.Build() };
            });
            services.AddTransient<IProductLineEntry<StringContext>, DefaultProductLineEntry>();
            return services;
        }

        /// <summary>
        /// 添加默认原始嵌套字生产线入口
        /// </summary>
        /// <param name="services"></param>
        /// <returns></returns>
        public static IServiceCollection AddDefaultRawSocketProductEntry(this IServiceCollection services)
        {
            services.AddSingleton<IProductLineBuilder<RawSocketContext>, ProductLineBuilder<RawSocketContext>>();
            services.AddSingleton<IProductLine<RawSocketContext>>((factory) =>
            {
                var startups = factory.GetServices<IStartup>();
                var serverBuilder = factory.GetRequiredService<IServerBuilder>();
                var hostEnv = factory.GetRequiredService<IHostEnvironment>();
                foreach (var item in startups) item.Configure(serverBuilder, hostEnv);
                var productLineBuilder = factory.GetRequiredService<IProductLineBuilder<RawSocketContext>>();
                return new DefaultProductLine<RawSocketContext>() { ProductLine = productLineBuilder.Build() };
            });
            services.AddTransient<IProductLineEntry<RawSocketContext>, DefaultRawSocketProductLineEntry>();
            return services;
        }

        /// <summary>
        /// 添加原始嵌套字生产线入口
        /// </summary>
        /// <typeparam name="TProductEntry"></typeparam>
        /// <typeparam name="TContext"></typeparam>
        /// <param name="services"></param>
        /// <returns></returns>
        public static IServiceCollection AddRawSocketProductEntry<TProductEntry, TContext>(this IServiceCollection services)
            where TProductEntry : class, IProductLineEntry<TContext>, new()
            where TContext : class
        {
            services.AddSingleton<IProductLineBuilder<TContext>, ProductLineBuilder<TContext>>();
            services.AddSingleton<IProductLine<TContext>>((factory) =>
            {
                var startups = factory.GetServices<IStartup>();
                var serverBuilder = factory.GetRequiredService<IServerBuilder>();
                var hostEnv = factory.GetRequiredService<IHostEnvironment>();
                foreach (var item in startups) item.Configure(serverBuilder, hostEnv);
                var productLineBuilder = factory.GetRequiredService<IProductLineBuilder<TContext>>();
                return new DefaultProductLine<TContext>() { ProductLine = productLineBuilder.Build() };
            });
            services.AddTransient<IProductLineEntry<TContext>, TProductEntry>();
            return services;
        }
    }
}
